package obg1.RagDoll;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.WakeLockOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.Scene.ITouchArea;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
import org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.source.ITextureSource;
import org.anddev.andengine.opengl.texture.source.ResourceTextureSource;
import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.constants.Constants;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Bitmap.Config;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.MotionEvent;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.joints.MouseJoint;
import com.badlogic.gdx.physics.box2d.joints.MouseJointDef;
import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef;

public class RagDollGame extends BaseGameActivity implements
		IAccelerometerListener, IOnSceneTouchListener, IOnAreaTouchListener {

	public int m_CameraWidth = 480 * 4;
	public int m_CameraHeight = 800 * 4;

	private final PhysicsWorld m_PhysicsWorld = new PhysicsWorld(new Vector2(0,
			SensorManager.GRAVITY_EARTH), true);

	private Body m_BodyGroundRight;
	private Body m_BodyGroundLeft;
	private Body m_BodyGround;
	private Body m_BodyTop;

	TextureRegion m_Head;
	TextureRegion m_Torso1;
	TextureRegion m_Torso2;
	TextureRegion m_Torso3;
	TextureRegion m_UpperArmLeft;
	TextureRegion m_UpperArmRight;
	TextureRegion m_LowerArmLeft;
	TextureRegion m_LowerArmRight;
	TextureRegion m_UpperLegLeft;
	TextureRegion m_UpperLegRight;
	TextureRegion m_LowerLegLeft;
	TextureRegion m_LowerLegRight;
	TextureRegion m_DebugTexture;

	Sprite m_HeadSprite;
	Sprite m_Torso1Sprite;
	Sprite m_Torso2Sprite;
	Sprite m_Torso3Sprite;
	Sprite m_UpperArmLeftSprite;
	Sprite m_UpperArmRightSprite;
	Sprite m_LowerArmLeftSprite;
	Sprite m_LowerArmRightSprite;
	Sprite m_UpperLegLeftSprite;
	Sprite m_UpperLegRightSprite;
	Sprite m_LowerLegLeftSprite;
	Sprite m_LowerLegRightSprite;

	Sprite m_DebugTextureSprite;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// setContentView(R.layout.main);
	}

	@Override
	public void onLoadComplete() {
		// TODO Auto-generated method stub
		  this.mEngine.enableVibrator(this);
	}

	@Override
	public Engine onLoadEngine() {

		Camera camera = new Camera(0, 0, m_CameraWidth, m_CameraHeight);
		EngineOptions options = new EngineOptions(true,
				ScreenOrientation.PORTRAIT, new RatioResolutionPolicy(
						m_CameraWidth, m_CameraHeight), camera);

		options.setNeedsMusic(true);
		options.setNeedsSound(true);
		options.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
		options.getTouchOptions().setRunOnUpdateThread(true);

		Engine engine = new Engine(options);

		return engine;
	}

	@Override
	public void onLoadResources() {
		// TODO Auto-generated method stub
		TextureRegionFactory.setAssetBasePath("gfx/");
		Texture texture = new Texture(1024, 1024, TextureOptions.DEFAULT);

		m_Head = TextureRegionFactory.createFromAsset(texture, this,
				"head.png", 0, 0);

		m_Torso1 = TextureRegionFactory.createFromAsset(texture, this,
				"torso1.png", 125, 0);
		m_Torso2 = TextureRegionFactory.createFromAsset(texture, this,
				"torso2.png", 125 + 150, 0);
		m_Torso3 = TextureRegionFactory.createFromAsset(texture, this,
				"torso3.png", 125 + 150 + 150, 0);

		m_UpperArmLeft = TextureRegionFactory.createFromAsset(texture, this,
				"upper_arm_left.png", 0, 125);
		m_UpperArmRight = TextureRegionFactory.createFromAsset(texture, this,
				"upper_arm_right.png", 180, 125);

		m_LowerArmLeft = TextureRegionFactory.createFromAsset(texture, this,
				"lower_arm_left.png", 180 + 180, 125);
		m_LowerArmRight = TextureRegionFactory.createFromAsset(texture, this,
				"lower_arm_right.png", 180 + 180 + 170, 125);

		m_UpperLegLeft = TextureRegionFactory.createFromAsset(texture, this,
				"upper_leg_left.png", 0, 125 + 65);

		m_UpperLegRight = TextureRegionFactory.createFromAsset(texture, this,
				"upper_leg_right.png", 75, 125 + 65);

		m_LowerLegLeft = TextureRegionFactory.createFromAsset(texture, this,
				"lower_leg_left.png", 75 + 75, 125 + 65);

		m_LowerLegRight = TextureRegionFactory.createFromAsset(texture, this,
				"lower_leg_right.png", 75 + 75 + 60, 125 + 65);

		// m_DebugTexture = TextureRegionFactory.extractFromTexture(texture, 0,
		// 0,
		// 1024, 1024);

		mEngine.getTextureManager().loadTexture(texture);
		
		
		this.enableAccelerometerSensor(this);
	}

	@Override
	public Scene onLoadScene() {
		// TODO Auto-generated method stub
		final Scene scene = new Scene(1);
		
		scene.setOnSceneTouchListener(this);
        scene.setOnAreaTouchListener(this);

		scene.setBackground(new ColorBackground(1, 1, 1));
		scene.setBackgroundEnabled(true);

		mGroundBody = this.m_PhysicsWorld.createBody(new BodyDef());
		
		float thickness = 10;
		float hOffset = 0;

		final Shape ground = new Rectangle(0, m_CameraHeight - 1,
				m_CameraWidth, thickness);
		final Shape roof = new Rectangle(0, -thickness + hOffset,
				m_CameraWidth, thickness);

		final Shape left = new Rectangle(-thickness, hOffset, thickness,
				m_CameraHeight - hOffset);
		final Shape right = new Rectangle(m_CameraWidth - 1, hOffset,
				thickness, m_CameraHeight - hOffset);
		
		final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(1.0f,
				0.2f, 0.1f);

		m_BodyTop = PhysicsFactory.createBoxBody(m_PhysicsWorld, roof,
				BodyType.StaticBody, wallFixtureDef);

		m_BodyGround = PhysicsFactory.createBoxBody(m_PhysicsWorld, ground,
				BodyType.StaticBody, wallFixtureDef);

		m_BodyGroundLeft = PhysicsFactory.createBoxBody(m_PhysicsWorld, left,
				BodyType.StaticBody, wallFixtureDef);

		m_BodyGroundRight = PhysicsFactory.createBoxBody(m_PhysicsWorld, right,
				BodyType.StaticBody, wallFixtureDef);

		createRagdoll();

		scene.registerTouchArea(m_HeadSprite);
		scene.registerTouchArea(m_Torso1Sprite);
		scene.registerTouchArea(m_Torso1Sprite);
		scene.registerTouchArea(m_Torso3Sprite);
		scene.registerTouchArea(m_UpperArmLeftSprite);
		scene.registerTouchArea(m_UpperArmRightSprite);		
		scene.registerTouchArea(m_LowerArmLeftSprite);
		scene.registerTouchArea(m_LowerArmRightSprite);		
		scene.registerTouchArea(m_UpperLegLeftSprite);
		scene.registerTouchArea(m_UpperLegRightSprite);		
		scene.registerTouchArea(m_LowerLegLeftSprite);
		scene.registerTouchArea(m_LowerLegRightSprite);
		
		scene.getChild(0).attachChild(m_HeadSprite);
		scene.getChild(0).attachChild(m_Torso1Sprite);
		scene.getChild(0).attachChild(m_Torso2Sprite);
		scene.getChild(0).attachChild(m_Torso3Sprite);
		scene.getChild(0).attachChild(m_UpperArmLeftSprite);
		scene.getChild(0).attachChild(m_UpperArmRightSprite);
		scene.getChild(0).attachChild(m_LowerArmLeftSprite);
		scene.getChild(0).attachChild(m_LowerArmRightSprite);
		scene.getChild(0).attachChild(m_UpperLegLeftSprite);
		scene.getChild(0).attachChild(m_UpperLegRightSprite);
		scene.getChild(0).attachChild(m_LowerLegLeftSprite);
		scene.getChild(0).attachChild(m_LowerLegRightSprite);

		// m_DebugTextureSprite = new Sprite(0, 0, m_DebugTexture);
		// scene.getChild(0).attachChild(m_DebugTextureSprite);

		scene.registerUpdateHandler(this.m_PhysicsWorld);

		return scene;
	}

	Vector2 getLeftPoint(Sprite sprite, Body body) {
		float w = sprite.getWidthScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		float h = sprite.getHeightScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		Vector2 pnt = body.getPosition();
		pnt.x -= w;
		pnt.y -= h;
		return pnt;
	}

	Vector2 getRightPoint(Sprite sprite, Body body) {
		float w = sprite.getWidthScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		float h = sprite.getHeightScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		Vector2 pnt = body.getPosition();
		pnt.x += w;
		pnt.y += h;
		return pnt;
	}

	Vector2 getTopPoint(Sprite sprite, Body body) {
		float h = sprite.getHeightScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		Vector2 pnt = body.getPosition();
		pnt.y -= h;
		return pnt;
	}

	Vector2 getBottomPoint(Sprite sprite, Body body) {
		float h = sprite.getHeightScaled() * 0.5f
				/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
		Vector2 pnt = body.getPosition();
		pnt.y += h;
		return pnt;
	}

	private void createRagdoll() {
		// TODO Auto-generated method stub

		m_HeadSprite = new Sprite(0, 0, m_Head);
		m_Torso1Sprite = new Sprite(0, 0, m_Torso1);
		m_Torso2Sprite = new Sprite(0, 0, m_Torso2);
		m_Torso3Sprite = new Sprite(0, 0, m_Torso3);
		m_UpperArmLeftSprite = new Sprite(0, 0, m_UpperArmLeft);
		m_UpperArmRightSprite = new Sprite(0, 0, m_UpperArmRight);
		m_LowerArmLeftSprite = new Sprite(0, 0, m_LowerArmLeft);
		m_LowerArmRightSprite = new Sprite(0, 0, m_LowerArmRight);
		m_UpperLegLeftSprite = new Sprite(0, 0, m_UpperLegLeft);
		m_UpperLegRightSprite = new Sprite(0, 0, m_UpperLegRight);
		m_LowerLegLeftSprite = new Sprite(0, 0, m_LowerLegLeft);
		m_LowerLegRightSprite = new Sprite(0, 0, m_LowerLegRight);

		RevoluteJointDef jd = new RevoluteJointDef();
		FixtureDef fixtureDef = new FixtureDef();

		float startX = m_CameraWidth / 2;
		float startY = m_CameraHeight / 2;

		// BODIES

		// Head
		fixtureDef.density = 1.0f;
		fixtureDef.friction = 0.1f;
		fixtureDef.restitution = 0.2f;
		m_HeadSprite.setPosition(startX, startY);

		Body head = PhysicsFactory.createCircleBody(m_PhysicsWorld,
				m_HeadSprite, BodyType.DynamicBody, fixtureDef);		
		
		m_HeadSprite.setUserData(head);
		
		// Makes him drunk ;)
		// head.applyLinearImpulse(new Vector2(50, 50), head.getWorldCenter());

		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_HeadSprite, head));

		// Torso1
		fixtureDef.density = 1.0f;
		fixtureDef.friction = 0.0f;
		fixtureDef.restitution = 1.0f;
		m_Torso1Sprite.setPosition(startX - 12.5f, startY + 125);

		Body torso1 = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_Torso1Sprite, BodyType.DynamicBody, fixtureDef);
		
		m_Torso1Sprite.setUserData(torso1);
		
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_Torso1Sprite, torso1));

		// Torso2
		m_Torso2Sprite.setPosition(startX - 12.5f, startY + 225 - 30);

		Body torso2 = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_Torso2Sprite, BodyType.DynamicBody, fixtureDef);
		
		m_Torso2Sprite.setUserData(torso2);

		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_Torso2Sprite, torso2));

		// Torso3
		m_Torso3Sprite.setPosition(startX - 12.5f, startY + 325 - 60);

		Body torso3 = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_Torso3Sprite, BodyType.DynamicBody, fixtureDef);
		
		m_Torso3Sprite.setUserData(torso3);

		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_Torso3Sprite, torso3));

		// UpperArm

		// L
		m_UpperArmLeftSprite.setPosition(startX - 167.5f - 30f, startY + 125);

		Body upperArmL = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_UpperArmLeftSprite, BodyType.DynamicBody, fixtureDef);

		m_UpperArmLeftSprite.setUserData(upperArmL);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_UpperArmLeftSprite, upperArmL));

		// R
		m_UpperArmRightSprite.setPosition(startX + 112.5f + 30f, startY + 125);

		Body upperArmR = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_UpperArmRightSprite, BodyType.DynamicBody, fixtureDef);
		
		m_UpperArmRightSprite.setUserData(upperArmR);

		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_UpperArmRightSprite, upperArmR));

		// LowerArm

		// L
		m_LowerArmLeftSprite.setPosition(startX - 347.5f - 10f, startY + 125);
		Body lowerArmL = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_LowerArmLeftSprite, BodyType.DynamicBody, fixtureDef);
		
		m_LowerArmLeftSprite.setUserData(lowerArmL);

		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_LowerArmLeftSprite, lowerArmL));

		// R
		m_LowerArmRightSprite.setPosition(startX + 292.5f + 10f, startY + 125);
		Body lowerArmR = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_LowerArmRightSprite, BodyType.DynamicBody, fixtureDef);

		m_LowerArmRightSprite.setUserData(lowerArmR);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_LowerArmRightSprite, lowerArmR));

		// UpperLeg

		// L
		m_UpperLegLeftSprite.setPosition(startX - 12.5f, startY + 425 - 40);
		Body upperLegL = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_UpperLegLeftSprite, BodyType.DynamicBody, fixtureDef);

		m_UpperLegLeftSprite.setUserData(upperLegL);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_UpperLegLeftSprite, upperLegL));

		// R
		m_UpperLegRightSprite.setPosition(startX + 62.5f, startY + 425 - 40);
		Body upperLegR = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_UpperLegRightSprite, BodyType.DynamicBody, fixtureDef);

		m_UpperLegRightSprite.setUserData(upperLegR);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_UpperLegRightSprite, upperLegR));

		// LowerLeg

		// L
		m_LowerLegLeftSprite.setPosition(startX + 2.5f, startY + 645 - 70);
		Body lowerLegL = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_LowerLegLeftSprite, BodyType.DynamicBody, fixtureDef);

		m_LowerLegLeftSprite.setUserData(lowerLegL);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_LowerLegLeftSprite, lowerLegL));

		// R
		m_LowerLegRightSprite.setPosition(startX + 62.5f, startY + 645 - 70);
		Body lowerLegR = PhysicsFactory.createBoxBody(m_PhysicsWorld,
				m_LowerLegRightSprite, BodyType.DynamicBody, fixtureDef);

		m_LowerLegRightSprite.setUserData(lowerLegR);
		
		m_PhysicsWorld.registerPhysicsConnector(new PhysicsConnector(
				m_LowerLegRightSprite, lowerLegR));

		// JOINTS
		jd.enableLimit = true;

		// Head to shoulders
		jd.lowerAngle = (float) (-40 / (180 / Math.PI));
		jd.upperAngle = (float) (40 / (180 / Math.PI));

		// jd.initialize(torso1,
		// head,head.getWorldPoint(head.getLocalCenter()));
		jd.initialize(torso1, head, getTopPoint(m_Torso1Sprite, torso1));
		m_PhysicsWorld.createJoint(jd);

		// Upper arm to shoulders
		// L
		jd.lowerAngle = (float) (-85 / (180 / Math.PI));
		jd.upperAngle = (float) (130 / (180 / Math.PI));

		// jd.initialize(torso1, upperArmL, getLeftPoint(m_Torso1Sprite,
		// torso1));
		jd.initialize(torso1, upperArmL, getRightPoint(m_UpperArmLeftSprite,
				upperArmL));

		m_PhysicsWorld.createJoint(jd);
		// R
		jd.lowerAngle = (float) (-130 / (180 / Math.PI));
		jd.upperAngle = (float) (85 / (180 / Math.PI));
		// jd.initialize(torso1, upperArmR, getRightPoint(m_Torso1Sprite,
		// torso1));
		jd.initialize(torso1, upperArmR, getLeftPoint(m_UpperArmRightSprite,
				upperArmR));

		m_PhysicsWorld.createJoint(jd);

		// Lower arm to upper arm
		// L
		jd.lowerAngle = (float) (-130 / (180 / Math.PI));
		jd.upperAngle = (float) (10 / (180 / Math.PI));
		jd.initialize(upperArmL, lowerArmL, getLeftPoint(m_UpperArmLeftSprite,
				upperArmL));
		m_PhysicsWorld.createJoint(jd);
		// R
		jd.lowerAngle = (float) (-10 / (180 / Math.PI));
		jd.upperAngle = (float) (130 / (180 / Math.PI));
		jd.initialize(upperArmR, lowerArmR, getRightPoint(
				m_UpperArmRightSprite, upperArmR));
		m_PhysicsWorld.createJoint(jd);

		// Shoulders/stomach
		jd.lowerAngle = (float) (-15 / (180 / Math.PI));
		jd.upperAngle = (float) (15 / (180 / Math.PI));
		jd.initialize(torso1, torso2, getBottomPoint(m_Torso1Sprite, torso1));
		m_PhysicsWorld.createJoint(jd);
		// Stomach/hips
		jd.initialize(torso2, torso3, getBottomPoint(m_Torso2Sprite, torso2));
		m_PhysicsWorld.createJoint(jd);

		// Torso to upper leg
		// L
		jd.lowerAngle = (float) (-25 / (180 / Math.PI));
		jd.upperAngle = (float) (45 / (180 / Math.PI));
		jd
				.initialize(torso3, upperLegL, getBottomPoint(m_Torso3Sprite,
						torso3));
		m_PhysicsWorld.createJoint(jd);
		// R
		jd.lowerAngle = (float) (-45 / (180 / Math.PI));
		jd.upperAngle = (float) (25 / (180 / Math.PI));
		jd
				.initialize(torso3, upperLegR, getBottomPoint(m_Torso3Sprite,
						torso3));
		m_PhysicsWorld.createJoint(jd);

		// Upper leg to lower leg
		// L
		jd.lowerAngle = (float) (-25 / (180 / Math.PI));
		jd.upperAngle = (float) (75 / (180 / Math.PI));
		jd.initialize(upperLegL, lowerLegL, getBottomPoint(
				m_UpperLegLeftSprite, upperLegL));
		m_PhysicsWorld.createJoint(jd);
		// R
		jd.lowerAngle = (float) (-75 / (180 / Math.PI));
		jd.upperAngle = (float) (25 / (180 / Math.PI));
		jd.initialize(upperLegR, lowerLegR, getBottomPoint(
				m_UpperLegLeftSprite, upperLegR));
		m_PhysicsWorld.createJoint(jd);
	}

	@Override
	public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
		// TODO Auto-generated method stub
		m_PhysicsWorld.setGravity(new Vector2(1 * pAccelerometerData.getY(),
				1 * pAccelerometerData.getX()));
	}
	
	 private MouseJoint mMouseJointActive;
     private Body mGroundBody;
     
     @Override
     public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
             if(pSceneTouchEvent.isActionDown()) {
                     final IShape face = (IShape) pTouchArea;
                     /*
                      * If we have a active MouseJoint, we are just moving it around
                      * instead of creating a second one.
                      */
                     if (this.mMouseJointActive == null) {
                             this.mEngine.vibrate(100);
                             this.mMouseJointActive = this.createMouseJoint(face, pTouchAreaLocalX, pTouchAreaLocalY);
                     }
                     return true;
             }
             return false;
     }
     
     @Override
     public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
             if (this.m_PhysicsWorld != null) {
                     switch(pSceneTouchEvent.getAction()) {
                          
                             case TouchEvent.ACTION_MOVE:
                                     if(this.mMouseJointActive != null) {
                                             final Vector2 vec = Vector2Pool.obtain(pSceneTouchEvent.getX() / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT, pSceneTouchEvent.getY() / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
                                             this.mMouseJointActive.setTarget(vec);
                                             Vector2Pool.recycle(vec);
                                     }
                                     return true;
                             case TouchEvent.ACTION_UP:
                                     if(this.mMouseJointActive != null) {
                                             this.m_PhysicsWorld.destroyJoint(this.mMouseJointActive);
                                             this.mMouseJointActive = null;
                                     }
                                     return true;
                     }
                     return false;
             }
             return false;
     }
     
     public MouseJoint createMouseJoint(final IShape pFace, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
         final Body body = (Body) pFace.getUserData();
         final MouseJointDef mouseJointDef = new MouseJointDef();

         final Vector2 localPoint = Vector2Pool.obtain((pTouchAreaLocalX - pFace.getWidth() * 0.5f) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT, (pTouchAreaLocalY - pFace.getHeight() * 0.5f) / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
         this.mGroundBody.setTransform(localPoint, 0);
         
         mouseJointDef.bodyA = this.mGroundBody;
         mouseJointDef.bodyB = body;
         mouseJointDef.dampingRatio = 0.95f;
         mouseJointDef.frequencyHz = 30f;
         mouseJointDef.maxForce = (200.0f * body.getMass());
         mouseJointDef.collideConnected = true;

         mouseJointDef.target.set(body.getWorldPoint(localPoint));
         Vector2Pool.recycle(localPoint);

         return (MouseJoint) this.m_PhysicsWorld.createJoint(mouseJointDef);
 }



}